package lib

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"strings"
)

var config = make(map[string]string)

var Opts = []string{"add", "rm", "run", "ls", "help"}

var OptsActionMap = map[string]string{
	"add":  "添加秘钥配置",
	"rm":   "删除秘钥",
	"run":  "计算校验码",
	"ls":   "查看已存在的秘钥",
	"help": "查看帮助",
}

var confPath string

var CmdArgs = struct {
	Opt    string
	Name   string
	Secret string
	Debug  bool
	Copy   bool // 是否拷贝
	Silent bool // 是否不显示，如果为true ,Copy 强制为true
}{}

func init() {
	filename, _ := Home()
	confPath = filename + "/.tow-factor-auth.config"
	loadConfig()
	initFlags()
}

func loadConfig() {
	confStr, err := ioutil.ReadFile(confPath)
	if err != nil {
		Log("配置文件读取失败")
	} else {
		err := json.Unmarshal(confStr, &config)
		if err != nil {
			Log("配置文件内容加载失败")
		}
	}
}

func GetConfig() map[string]string {
	return config
}

func Log(s string) {
	if CmdArgs.Debug {
		fmt.Println(s)
	}
}

func initFlags() {
	if len(os.Args) > 1 && strings.Index(os.Args[1], "-") != 0 {
		opt := os.Args[1]
		for _, v := range Opts {
			if strings.EqualFold(v, opt) {
				CmdArgs.Opt = v
				opt = v
				break
			}
		}
		if CmdArgs.Opt == "" {
			panic("不支持的命令：" + opt)
		}
		subFlag := flag.NewFlagSet(opt, flag.ExitOnError)
		confFlag(subFlag)
		_ = subFlag.Parse(os.Args[2:])
		subFlag.Usage = func() {
			fmt.Printf(`Usage of %s %s:`, opt, OptsActionMap[opt])
			subFlag.PrintDefaults()
		}
	} else {
		flag.StringVar(&CmdArgs.Opt, "opt", "run", "需要执行的命令")
		confFlag(flag.CommandLine)
		flag.Parse()
	}
	if CmdArgs.Silent {
		CmdArgs.Copy = true
	}
	Log(fmt.Sprintf("你输入的 opt:%s name:%s secret:%s debug %v", CmdArgs.Opt, CmdArgs.Name, CmdArgs.Secret, CmdArgs.Debug))
}

func confFlag(myFlag *flag.FlagSet) *flag.FlagSet {
	myFlag.StringVar(&CmdArgs.Name, "name", "default", "名字")
	myFlag.StringVar(&CmdArgs.Secret, "secret", "", "秘钥")
	myFlag.BoolVar(&CmdArgs.Debug, "debug", false, "debug 模式")
	myFlag.BoolVar(&CmdArgs.Copy, "copy", false, "是否将结果拷贝到粘贴板")
	myFlag.BoolVar(&CmdArgs.Silent, "silent", false, "是否静默结果，为true 时，copy 值强制为true")
	return myFlag
}

func GetSecret() string {
	if len(config) == 0 {
		panic("配置文件为空")
	}
	secret, ok := config[CmdArgs.Name]
	if ok {
		return secret
	} else {
		panic(CmdArgs.Name + " 的Secret不存在")
	}
	return ""
}

func Add(name, secret string) {
	config[name] = secret
	strBytes, _ := json.Marshal(config)
	ioutil.WriteFile(confPath, strBytes, 0777)
}

func Rm(name string) {
	delete(config, name)
	strBytes, _ := json.Marshal(config)
	ioutil.WriteFile(confPath, strBytes, 0777)
}
